//: [Previous](@previous)

import Foundation


func doWork(block: () -> ()) {
    block()
}

func doWorkAsync(block: @escaping () -> ()) {
    DispatchQueue.main.async {
        block()
    }
}

class S {
    var foo = "foo"
    
    func method1() {
        doWork {
            print(foo)
        }
        foo = "bar"
    }
    
    func method2() {
        doWorkAsync {
            print(self.foo)
        }
        foo = "bar"
    }
    
    func method3() {
        doWorkAsync {
            [weak self] _ in
            print(self?.foo)
        }
    }
}

//S().method1()
//S().method2()

//在协议或者父类中定义了@escaping，在实现协议或者父类的子类中也要生命为@escaping
protocol P {
    func work(b: @escaping () -> ())
}

class C: P {
    func work(b: @escaping () -> ()) {
        DispatchQueue.main.async {
            print("in C")
        }
        b()
    }
}

// MARK: Optional Chaining
class Toy {
    let name: String
    init(name: String) {
        self.name = name
    }
}

class Pet {
    var toy: Toy?
}

class Child {
    var pet: Pet?
}

let xiaoming = Child()

let toyName = xiaoming.pet?.toy?.name //toyName 为String?

if let toyName = xiaoming.pet?.toy?.name {
    
}

extension Toy {
    func play() {
        print("Play")
    }
}
xiaoming.pet?.toy?.play()

//错误写法 child.pet?.toy?.play()的返回值是()?  Void? 而不是()  Void
var playClosure1 = {(child: Child) -> () in child.pet?.toy?.play()}

//正确写法
let playClosure2 = {(chlid: Child) -> ()? in chlid.pet?.toy?.play()}

//通过OptionalBinding判断方法是否调用成功
if let result: () = playClosure2(xiaoming) {
    print("好开心")
} else {
    print("没有玩具可以玩")
}


// MARK: 重载操作符
struct Vector2D {
    var x = 0.0
    var y = 0.0
}

func +(left: Vector2D, right: Vector2D) -> Vector2D {
    return Vector2D(x: left.x + right.x, y: left.y + left.y)
}

let v1 = Vector2D(x: 1, y: 2)
let v2 = Vector2D(x: 2, y: 3)
let v4 = v1 + v2
print(v4)

//操作符优先级别
precedencegroup DotProducePrecedence {
    associativity: none //结合律
    higherThan: MultiplicationPrecedence //优先级
}

//infix 中位操作符， 还有prefix和postfix
infix operator +*: DotProducePrecedence

//let result = v1 +* v2
//print(result)
